package com.ramnight.unify.boot.spring;

import java.io.IOException;
import java.util.Optional;
import java.util.Properties;

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;

public class SpringPropKit {

	// 改变启动yml配置文件
	public static void setApplicationYml(String yml) {
		System.setProperty("spring.config.location", "classpath:" + yml);
	}

	public static void disableAutoConfiguration() {
		System.setProperty("spring.boot.enableautoconfiguration", "false");
	}

	public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(String yml) {
		PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
		ClassPathResource resource = new ClassPathResource(yml);
		if (!resource.exists()) {
			return configurer;
		}

		YamlPropertiesFactoryBean yamlProFb = new YamlPropertiesFactoryBean();
		yamlProFb.setResources(resource);
		configurer.setProperties(yamlProFb.getObject());
		return configurer;
	}

	public static class YmlPropertySourceFactory extends DefaultPropertySourceFactory {
		@Override
		public org.springframework.core.env.PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
			String sourceName = Optional.ofNullable(name).orElse(resource.getResource().getFilename());
			if (!resource.getResource().exists()) {
				throw new RuntimeException(name + " not found");
			} else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) {
				Properties propertiesFromYaml = loadYaml(resource);
				return new PropertiesPropertySource(sourceName, propertiesFromYaml);
			} else {
				return super.createPropertySource(name, resource);
			}
		}

		/**
		 * load yaml file to properties
		 *
		 * @param resource
		 * @return
		 * @throws IOException
		 */
		private Properties loadYaml(EncodedResource resource) throws IOException {
			YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
			factory.setResources(resource.getResource());
			factory.afterPropertiesSet();
			return factory.getObject();
		}
	}
}
